home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / randist / poisson.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-14  |  2.0 KB  |  94 lines

  1. /* randist/poisson.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 James Theiler, Brian Gough
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. #include <config.h>
  21. #include <math.h>
  22. #include <gsl/gsl_sf_gamma.h>
  23. #include <gsl/gsl_rng.h>
  24. #include <gsl/gsl_randist.h>
  25.  
  26. /* The poisson distribution has the form
  27.  
  28.    p(n) = (mu^n / n!) exp(-mu) 
  29.  
  30.    for n = 0, 1, 2, ... . The method used here is the one from Knuth. */
  31.  
  32. unsigned int
  33. gsl_ran_poisson (const gsl_rng * r, double mu)
  34. {
  35.   double emu;
  36.   double prod = 1.0;
  37.   unsigned int k = 0;
  38.  
  39.   while (mu > 10)
  40.     {
  41.       unsigned int m = mu * (7.0 / 8.0);
  42.  
  43.       double X = gsl_ran_gamma_int (r, m);
  44.  
  45.       if (X >= mu)
  46.     {
  47.       return k + gsl_ran_binomial (r, mu / X, m - 1);
  48.     }
  49.       else
  50.     {
  51.       k += m;
  52.       mu -= X; 
  53.     }
  54.     }
  55.  
  56.   /* This following method works well when mu is small */
  57.  
  58.   emu = exp (-mu);
  59.  
  60.   do
  61.     {
  62.       prod *= gsl_rng_uniform (r);
  63.       k++;
  64.     }
  65.   while (prod > emu);
  66.  
  67.   return k - 1;
  68.  
  69. }
  70.  
  71. void
  72. gsl_ran_poisson_array (const gsl_rng * r, size_t n, unsigned int array[],
  73.                double mu)
  74. {
  75.   size_t i;
  76.  
  77.   for (i = 0; i < n; i++)
  78.     {
  79.       array[i] = gsl_ran_poisson (r, mu);
  80.     }
  81.  
  82.   return;
  83. }
  84.  
  85. double
  86. gsl_ran_poisson_pdf (const unsigned int k, const double mu)
  87. {
  88.   double p;
  89.   double lf = gsl_sf_lnfact (k); 
  90.  
  91.   p = exp (log (mu) * k - lf - mu);
  92.   return p;
  93. }
  94.